﻿using System.Text.RegularExpressions;
using static SharpParser.Parsers;

namespace SharpParser;

public static class Program
{
    public static void Main(string[] args)
    {
        var httpParser = HttpParsers.HttpResponse(@"HTTP/1.1 200 OK
Date: Wed, 18 Apr 2024 12:00:00 GMT
Server: Apache/2.4.1 (Unix)
Last-Modified: Wed, 18 Apr 2024 11:00:00 GMT
Content-Length: 12345
Content-Type: text/html; charset=UTF-8

<!DOCTYPE html>
<html>
<head>
    <title>Example Page</title>
</head>
<body>
    <h1>Hello, World!</h1>
    <!-- The rest of the HTML content -->
</body>
</html>
");
    }

    public static class HttpParsers
    {
        public static Parser<string> Version => Token;

        public static Parser<int> StatusCode => input =>
        {
            var match = Regex.Match(input, @"^\d+");
            if (!match.Success)
                return null;
            return new Result<int> { Value = int.Parse(match.Value), Rest = input.Substring(match.Length) };
        };

        public static Parser<string> StatusText => Line;

        public static Parser<(string Name, string Value)> Header => And(Take(AnyString, ':'), Line);

        public static Parser<(string Version, int StatusCode, string StatusText, List<(string Name, string Value)> Headers, string Body)> HttpResponse => input =>
        {
            var statusLineParser = And(Version, Skip(WhiteSpace), StatusCode, Skip(WhiteSpace), StatusText);
            var statusLineResult = statusLineParser(input);
            if (statusLineResult == null)
                return null;

            var headersParser = ZeroOrMore(Header);
            var headersResult = headersParser(statusLineResult.Rest);
            if (headersResult == null)
                return null;

            var bodyParser = Take(AnyString, '\0');
            var bodyResult = bodyParser(headersResult.Rest);
            if (bodyResult == null)
                return null;

            return new Result<(string Version, int StatusCode, string StatusText, List<(string Name, string Value)> Headers, string Body)>
            {
                Value = (statusLineResult.Value.Value1, statusLineResult.Value.Value3, statusLineResult.Value.Value5, headersResult.Value, bodyResult.Value),
                Rest = bodyResult.Rest
            };
        };
    }
}



